/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
package com.godenwater.recv.server.yf;

import cn.gov.mwr.sl651.*;
import cn.gov.mwr.sl651.body.Up36Body;
import cn.gov.mwr.sl651.command.UpCommand;
import cn.gov.mwr.sl651.parser.HexParser;
import cn.gov.mwr.sl651.utils.ByteUtil;
import cn.gov.mwr.sl651.utils.StcdParser;
import com.godenwater.yanyu.YYBuilder;
import com.godenwater.recv.model.CommonMessage;
import org.apache.commons.lang.StringUtils;
import org.apache.mina.core.future.ConnectFuture;
import org.apache.mina.core.service.IoConnector;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.transport.socket.SocketSessionConfig;
import org.apache.mina.transport.socket.nio.NioSocketConnector;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;

/**
 * An UDP client taht just send thousands of small messages to a UdpServer.
 * <p>
 * This class is used for performance test purposes. It does nothing at all, but
 * send a message repetitly to a server.
 *
 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
 */
public class YfClient extends IoHandlerAdapter implements Runnable {

    private Logger logger = LoggerFactory.getLogger(YfClient.class);

    /**
     * The connector
     */
    private IoConnector connector;

    /**
     * The session
     */
    private static IoSession session;

    private boolean received = false;

    private UpCommand cmd = new UpCommand();

    private byte upDown = Symbol.UP;

    private int mPort = 5280;


    /**
     * Create the UdpClient's instance
     */
    public YfClient() {
        connector = new NioSocketConnector();
        connector.getFilterChain().addLast("codec",
                new ProtocolCodecFilter(new YfClientCodecFactory()));
        connector.setHandler(this);

        SocketSessionConfig dcfg = (SocketSessionConfig) connector
                .getSessionConfig();
        dcfg.setWriteTimeout(30);

        // 创建连接
        // ConnectFuture connFuture = connector.connect(new InetSocketAddress(
        // "localhost", 50170));// 101.200.195.117
        ConnectFuture connFuture = connector.connect(new InetSocketAddress(
                "127.0.0.1", mPort));//5800,6688,5888
        // 等待是否连接成功，相当于是转异步执行为同步执行。
        connFuture.awaitUninterruptibly();

        // 获取session
        session = connFuture.getSession();

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void exceptionCaught(IoSession session, Throwable cause)
            throws Exception {
        // cause.printStackTrace();
        logger.info(">> Client 会话出现异常  " + session.getRemoteAddress() + " \t"
                + cause.getMessage(), cause);
    }

    public void viewInfo(HexParser parser, IMessage message) throws Exception {

        IMessageHeader header = message.getHeader();
        IMessageBody body = parser.parse36Body(message.getBody().getContent());

        Up36Body body36 = (Up36Body) body;

        System.out.println("******* 中心站查询遥测站实时数据 *******");
        System.out.println("原始包长度：" + header.getBodySize() + "字节");
        // System.out
        // .println("原始包信息：" + );
        System.out.println("中心站地址："
                + ByteUtil.toHexString(header.getCenterAddr()));
        System.out.println("水文特征码：00，水文测站编码："
                + StcdParser.parseStcd(header.getStationAddr()));
        System.out.println("密码：" + ByteUtil.toHexString(header.getPassword()));
        System.out.println("功能码：" + ByteUtil.toHexString(header.getFuncCode()));
        System.out.println("流水号：" + body36.getSerialId() + "，发报时间："
                + body36.getSendDate());

    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void messageReceived(IoSession session, Object message)
            throws Exception {
        received = true;

        // 纯粹只处理报文，此消息体已经被解码为单体报文
        CommonMessage msg = (CommonMessage) message;
        Object msgheader = msg.getHeader();
        if (msgheader instanceof cn.gov.mwr.sl651.header.HexHeader) {

            IMessageHeader header = (IMessageHeader) msg
                    .getHeader();
            String hHeader = HydroBuilder.toHexString(header,
                    Symbol.DOWN);
            String hBody = ByteUtil.toHexString(msg.getContent());
            String hEof = ByteUtil.toHexString(msg.getEOF());
            String hCrc = ByteUtil.toHexString(msg.getCRC());
            System.out.println(hHeader + hBody + hEof + hCrc);

        } else if (msgheader instanceof cn.gov.mwr.sl651.header.AscHeader) {

            IMessageHeader header = (IMessageHeader) msg
                    .getHeader();

            String hHeader = HydroBuilder.toHexString(header,
                    Symbol.DOWN);
            String hBody = ByteUtil.toHexString(msg.getContent());
            String hEof = ByteUtil.toHexString(msg.getEOF());
            String hCrc = ByteUtil.toHexString(msg.getCRC());
            System.out.println(hHeader + hBody + hEof + hCrc);

        } else if (msgheader instanceof com.godenwater.yanyu.YYMessageHeader) {

            com.godenwater.yanyu.IMessageHeader header = (com.godenwater.yanyu.IMessageHeader) msg
                    .getHeader();

            String hHeader = YYBuilder.toHexString(header,
                    Symbol.DOWN);
            String hBody = ByteUtil.toHexString(msg.getContent());
            String hEof = ByteUtil.toHexString(msg.getEOF());
            String hCrc = ByteUtil.toHexString(msg.getCRC());
            System.out.println(hHeader + hBody + hEof + hCrc);

        } else {
            // 未知的报文

        }


    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void sessionClosed(IoSession session) throws Exception {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void sessionCreated(IoSession session) throws Exception {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void sessionIdle(IoSession session, IdleStatus status)
            throws Exception {
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void sessionOpened(IoSession session) throws Exception {
    }

    public void run() {
        int i = 1;
        //宏电报文
        //line = "7B01001631333931323334353637380AAB570D0FA27B";//
        //sendMessage(StringUtils.replace(line, " ", ""));

        String line = "";
        line = "7B09001031333931323334353637387B7E11FF0E3F1506241100000000000000000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF1210FFFFFFFFFFFFFFFFFFFF00032DCD";
        //line = "7E 13 78 0E A0 13 10 29 16 00 00 0E 00 00 00 0E 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 12 10 00 00 00 00 00 00 00 00 00 00 01 20 20 20 31 2E 36 35 33 20 20 20 31 2E 37 34 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 20 20 20 31 2E 36 35 33 00 17 09 BD";
        //line = "7E 63 05 09 57 12 08 08 07 51 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 12 30 FF FF FF FF 00 10 FF FF FF FF 11 03 F6 12 04 5A 13 03 F6 14 03 F6 15 03 F6 16 03 F6 FF FF FF FF FF FF 00 17 2C 75";
        line = "7e112d0e9f17031116000000000000000000000000000000000000000aaa0aaa0aaa0aaa0aaa0aaa0aaa0aaa0aaa0aaa0aaa0aaa1360ffffffffffffffffffff202020302e363835202020302e363835202020312e363831202020312e373637202020312e373637202020312e373637202020312e373637202020312e373637202020312e373637202020312e363336202020312e363336202020312e36333600032a2d";
        sendMessage(line);


    }

    public void stop() {
        if (connector.isActive()) {
            connector.dispose(true);
        }
    }


    /**
     * 小时报
     */
    public void sendMessage(String hexString) {

        hexString = StringUtils.replace(hexString, " ", "");
        byte[] message = hexString.getBytes();
        session.write(message);
    }



    /**
     * The main method : instanciates a client, and send N messages. We sleep
     * between each K messages sent, to avoid the server saturation.
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {


        // ----------------------------------------------------------
//        for (int i = 1; i <= 1; i++) {
//            YfClient client = new YfClient();
//            Thread thread = new Thread(client);
//            thread.start();
//        }

        YfClient client = new YfClient();
        String line = "$30151G22010201120326001297065535323906553532390655353239065535323906553532390655353239065535323906553532390655353239065535323906553532390655353239";

       line = "$40231G22120202170315011276003577532400357753240035775324003577532400357753240035775324003577532400357753240035775324003577532400357753240035775324";
        client.sendMessage(line);

        System.out.println("OOOOOOOOOOOOOOOOOOOOOOOOOKKKKKKKKKKKKKKKKKKKKKKKKKKKK");

    }
}
